#ifndef LIGHT_H
#define LIGHT_H

#include <Windows.h>
#include <d3dx11effect.h>
#include <xnamath.h>

class Mesh;

struct Light_Params
{
	XMFLOAT4 diffuse;
	XMFLOAT4 specular;
	XMFLOAT4 direction;
	XMFLOAT4 position;
	XMFLOAT4 attenuation;
};


class Light
{

public:
	Light(float diff_r, float diff_g, float diff_b, float spec_r, float spec_g, float spec_b, 
				float dir_x, float dir_y, float dir_z, float pos_x, float pos_y, float pos_z, 
				float att_x, float att_y, float att_z, float cutoff, float exp);
	Light();
	~Light();

	static const int LIGHT_DIRECTIONAL = 0;
	static const int LIGHT_SPOT        = 1;

	ID3D11ShaderResourceView* getShadowMapSRV() const { return srv_shadow; }
	ID3D11DepthStencilView* getShadowMapDSV() const	{ return dsv_shadow; }

	const Light_Params& getLightStructure() const { return light; }

	void setPosition(float x, float y, float z)	 { light.position = XMFLOAT4(x, y, z, 1.0f); }
	void setDirection(float x, float y, float z) { light.direction = XMFLOAT4(x, y, z, 0.0f); }
	void setDiffuse(float r, float g, float b)	 { light.diffuse.x = r; light.diffuse.y = g; light.diffuse.z = b; }	
	void setSpecular(float r, float g, float b)  { light.specular.x = r; light.specular.y = g; light.specular.z = b; }
	void setAttenuation(float x, float y, float z) { light.attenuation.x = x; light.attenuation.y = y; light.attenuation.z = z; }
	void setExponent(float e)						{ light.diffuse.w = e; }
	void setCutOff(float angle)						{ light.specular.w = angle; }
	void setType(float i)							{ light.attenuation.w = (float)i; }

	XMFLOAT4 getPosition()		const		{ return light.position;	}
	XMFLOAT4 getDirection()		const		{ return light.direction;	}
	XMFLOAT4 getDiffuse()		const		{ return light.diffuse;		}
	XMFLOAT4 getSpecular()		const		{ return light.specular;	}
	XMFLOAT4 getAttenuation()	const		{ return light.attenuation; }
	float getExponent()			const		{ return light.diffuse.w;	}
	float getCutOff()			const		{ return light.specular.w;	}

	void createShadowResources(int w,  ID3D11Device* g_dev, ID3D11DeviceContext* _g_context);
	void drawShadowMap(const Mesh* mesh);

	XMMATRIX getViewProjMatrix() const;

	void startShadowMapDraw();
	void endShadowMapDraw();

	void setShadowMapEffect(ID3DX11Effect* fx) { _fx_shadowMap = fx; _fx_shadowMap->AddRef(); }

	int type() const { return (int)light.attenuation.w; }

	int getShadowMapSize() const { return shadow_size; };

private:

	int shadow_size;

	Light_Params light;

	bool bHasShadows;

	ID3DX11Effect* _fx_shadowMap;
	ID3DX11EffectMatrixVariable*	fx_m_L_WorldViewProj;
	
	ID3D11Device* _device;
	ID3D11DeviceContext* _context;

	ID3D11Texture2D* tex_shadow;
	ID3D11DepthStencilView* dsv_shadow;
	ID3D11ShaderResourceView* srv_shadow;

	ID3D11RenderTargetView* rtv;
	ID3D11DepthStencilView* dsv;
	D3D11_VIEWPORT vp;

};


#endif